home *** CD-ROM | disk | FTP | other *** search
/ Carousel / CAROUSEL.cdr / mactosh / utilprn / hpdeskje.sit / HPDJet ƒ / PDEF4.c < prev    next >
C/C++ Source or Header  |  1989-04-02  |  37KB  |  1,306 lines

  1. /* 02.04.1989  amn  (latest edit) */
  2.  
  3. /* PDEF4.c  -  printer driver style and job dialog handler for Macintosh and HP DeskJet. */
  4.  
  5. /* Compiles into 'PDEF' resource, id 4, name ''. */
  6. /* We cannot use any global variables in this code.  However, the globals of the */
  7. /* low-level driver (XPrint) are available thru the handle 'dCtlStorage' in the */
  8. /* driver's device control entry. */
  9.  
  10. /* This resource is placed into the printer resource file */
  11. /* 'HP DeskJet', type 'PRER', creator 's89^' as */
  12. /* 'PDEF' 4 '' by 'PRER_Builder' utility program.  This utility adds a small jump */
  13. /* table in front of the code produced by LightspeedC. */
  14.  
  15. /* The procedures in this file generate print records for the printing application */
  16. /* to be used in conjunction with our high-level driver ('PDEF' 0/'PDEF' 1&5). */
  17. /* The print record data structure is exposed to applications, thus they may */
  18. /*  - synthetize it */
  19. /*  - reuse a record made by another driver */
  20. /*  - let us present a default print record */
  21. /*  - make modifications to it */
  22. /*  - etc. */
  23. /* Fortunately, they must validate this record using 'PrValidate()'. */
  24. /* ... */
  25.  
  26. /* Authors:  Ari Mujunen (amn@hutcs.hut.fi) and Olli Arnberg (oar@hutcs.hut.fi). */
  27. /* Copyright Ari Mujunen, Olli Arnberg 1989. */
  28. /* You may redistribute the driver (=printer resource file, source files, */
  29. /* documentation file(s), and the file 'Copyright and Source Offer') */
  30. /* only _non-commercially_ and _in its entirety_. */
  31. /* See the file 'Copyright and Source Offer' and/or documentation for details. */
  32. /* Acknowledgements:  Special thanks to Mr. Earle R. Horton for his 'Daisy' */
  33. /* daisywheel printer driver and its source code published in 'MacTutor', Nov-Dec 1987. */
  34. /* This driver served as a basis and inspiration for our work.  It also */
  35. /* proofed that a Macintosh printer driver can be done despite the lack of */
  36. /* documentation from Apple. */
  37.  
  38. /* Change history: */
  39. /* Version  When        Who      Why */
  40. /* 2.0      20.11.1988  amn      Original rewrite. */
  41. /*          21.11.1988  amn      'Other' paper size. */
  42. /*          25.11.1988  amn      Read the printed listing... */
  43. /*          26.11.1988  amn      Searching for some kind of memory overwrite. */
  44. /*          27.11.1988  amn      It wasn't here, it was in XPrint.c. */
  45. /*          09.12.1988  amn      Number fields in dialogs. */
  46. /*          08.03.1989  amn, oar Help. */
  47. /*          23.03.1989  amn, oar Allowing added dialog items to receive any keystroke. */
  48. /*          25.03.1989  amn      Enlarge/reduce percentages. */
  49. /*          26.03.1989  amn      Reframe OK-button when update messages arrive. */
  50. /*          28.03.1989  amn      Settable printer origin. */
  51. /*          30.03.1989  amn, oar Fine-tuning hard-coded default print record. */
  52. /*          31.03.1989  amn      Setting permanent spool file flag. */
  53. /* 2.1      02.04.1989  amn,oar  Released version. */
  54.  
  55.  
  56. #include "common_mac_includes.h"
  57.  
  58. /* Mac OS includes specific to this module: */
  59. /* none yet */
  60.  
  61. #include "prglobals.h"
  62.  
  63.  
  64. /* Paper size number is used to index the array of paper size descriptors  */
  65. /* in the resource 'PREC' 4. */
  66. /* (Apple's drivers use 'PREC' 3, but some applications know what is there and */
  67. /* try to supply more paper sizes by themselves.  We would like to be able to */
  68. /* emulate different page sizes using the same paper size -- this is why we don't */
  69. /* use a similar PREC 3.) */
  70. /* Add a number from each of the following three groups to get the correct number. */
  71. #define PAPER_A4 0
  72. #define PAPER_US_LETTER 1
  73. #define PAPER_US_LEGAL 2
  74. #define PAPER_ENVELOPE 3
  75. #define PAPER_DEFAULT PAPER_A4
  76. #define PAPER_MASK 0x0003
  77.  
  78. #define PRINTER_IMAGE 0
  79. #define PRINTER_LQ 4
  80. #define PRINTER_LASER 8
  81. #define PRINTER_HPDESKJET 12
  82. #define PRINTER_DEFAULT PRINTER_LASER
  83. #define PRINTER_NUMBER_OF 4
  84. #define PRINTER_MASK 0x000C
  85.  
  86. #define PIXELS_BEAUTIFUL 0
  87. #define PIXELS_EXACT 16
  88. #define PIXELS_DEFAULT PIXELS_BEAUTIFUL
  89. #define PIXELS_NUMBER_OF 16
  90. #define PIXELS_MASK 0x0010
  91.  
  92.  
  93. /* Dialog id's and item numbers in resource file. */
  94.  
  95. /* Page setup (style) dialog: */
  96.  
  97. #define STYLEDIALOG (-8192)
  98. #define STYLEHELPDIALOG (-8137)
  99.  
  100. #define HPICON 5
  101. #define A4BUTTON 6
  102. #define USLETTERBUTTON 7
  103. #define USLEGALBUTTON 8
  104. #define ENVELOPEBUTTON 9
  105. #define OTHERBUTTON 10
  106. #define EXACTBOX 11
  107. #define APPLEWRITERBOX 12
  108. #define IMAGEBUTTON 13
  109. #define LQBUTTON 14
  110. #define LASERBUTTON 15
  111. #define PAPERWIDTHNUM 17
  112. #define PAPERHEIGHTNUM 18
  113. #define MARGINTOPNUM 20
  114. #define MARGINLEFTNUM 21
  115. #define TALLBUTTON 23
  116. #define WIDEBUTTON 24
  117. #define MARGINBOTTOMNUM 27
  118. #define MARGINRIGHTNUM 28
  119. #define RESVNUM 29
  120. #define RESHNUM 30
  121. #define STYLEHELPBUTTON 31
  122. #define STYLESCALENUM 32
  123. #define LASTSTYLEITEM 32
  124.  
  125.  
  126. /* Printing (job) dialog: */
  127.  
  128. #define JOBDIALOG (-8191)
  129. #define JOBHELPDIALOG (-8161)
  130.  
  131. #define DPI300BUTTON 3
  132. #define DPI150BUTTON 4
  133. #define DPI100BUTTON 5
  134. #define DPI75BUTTON 6
  135. #define DRAFTBUTTON 7
  136. #define ALLBUTTON 8
  137. #define RANGEBUTTON 9
  138. #define FROMNUM    16
  139. #define TONUM 18
  140. #define COPIESNUM 20
  141. #define AUTOMATICBUTTON 10
  142. #define MANUALBUTTON 11
  143. #define JOBHELPBUTTON 22
  144. #define JOBSCALENUM 23
  145. #define LASTJOBITEM 23
  146.  
  147. /* Types used in this module. */
  148.  
  149. /* This struct contains info from paper size description resource PREC 4. */
  150. typedef struct tPaperSizeInfo {
  151.     int        iVRes;
  152.     int        iHRes;
  153.     Rect    rPage;
  154.     Rect    rPaper;
  155.     int        iPageV;
  156.     int        iPageH;
  157.     TFeed    feed;
  158.     SignedByte    fill;
  159. } tPaperSizeInfo;
  160.  
  161. typedef struct tAllSizesInfo {
  162.     int iNumberOfItems;
  163.     tPaperSizeInfo sSizeInfo[1];
  164. } tAllSizesInfo, **htAllSizesInfo;
  165.  
  166.  
  167.  
  168. /* Function prototypes. */
  169.  
  170. void main(int);
  171.  
  172. /* Fill default print record. */
  173. pascal void myPrintDefault(THPrint);
  174.  
  175. /* Print style & job dialogs. */
  176. pascal Boolean myPrStlDialog(THPrint);
  177. pascal Boolean myPrJobDialog(THPrint);
  178.  
  179. /* Set up style/job dialog. */
  180. pascal TPPrDlg myPrStlInit(THPrint);
  181. pascal TPPrDlg myPrJobInit(THPrint);
  182. TPPrDlg allocatePrDialog(void);
  183.  
  184. /* Print dialog supervisor. */
  185. pascal Boolean myPrDlgMain(THPrint, ProcPtr);
  186.  
  187. /* Validate print record. */
  188. pascal Boolean myPrValidate(THPrint);
  189.  
  190. /* Copy information set in job dialog. */
  191. pascal void myPrJobMerge(THPrint, THPrint);
  192.  
  193. /* Filter dialog events. */
  194. pascal Boolean myStyleFilter(TPPrDlg, EventRecord *, int *);
  195. pascal Boolean myJobFilter(TPPrDlg, EventRecord *, int *);
  196.  
  197. /* ??? */
  198. pascal void handleStyleItems(TPPrDlg, int);
  199. void setPaperSizeFieldsInPrintRecord(TPPrDlg, THPrint);
  200. void setOtherPaperSizeInDialog(TPPrDlg, THPrint);
  201. pascal void handleJobItems(TPPrDlg, int);
  202.  
  203. /* Make a hard-coded default print record. */
  204. void mkDefault(THPrint);
  205.  
  206. /* Is the print record valid ? */
  207. Boolean isValid(THPrint);
  208. Boolean isCorrectableAndWasUpdated(THPrint);
  209.  
  210. /* Paper sizes in 'PREC' 4 resource. */
  211. int whichPaperSize(THPrint);
  212. Boolean updatePaperSize(THPrint, int);
  213.  
  214. /* Dialog item handling. */
  215. #define DIALOG_PTR_TYPE_TODAY TPPrDlg
  216. #include "dialog_item_handling.h"
  217. void blankStringItem(TPPrDlg, int);
  218.  
  219.  
  220.  
  221. /* Function definitions. */
  222.  
  223.  
  224. void
  225. main(routineSelector)
  226. int routineSelector;
  227. {
  228.     /* The jump table code inserted before our code resource by 'PRER_Builder' */
  229.     /* utility program pushes a word onto stack indicating which routine is called. */
  230.     /* We pop it off the stack and select an appropriate routine. */
  231.     
  232.     switch(routineSelector) {
  233.         case 0:
  234.             asm {
  235.                 unlk a6  ;; LSC generates an 'link' instruction to access parameters
  236.                 move.l (a7)+, d0  ;; pop return address to our jump table code (discarded)
  237.                 move.w (a7)+, d0  ;; pop argument 'routineSelector'
  238.                 jmp myPrintDefault
  239.             }
  240.         case 1:
  241.             asm {
  242.                 unlk a6
  243.                 move.l (a7)+, d0
  244.                 move.w (a7)+, d0
  245.                 jmp myPrStlDialog
  246.             }
  247.         case 2:
  248.             asm {
  249.                 unlk a6
  250.                 move.l (a7)+, d0
  251.                 move.w (a7)+, d0
  252.                 jmp    myPrJobDialog
  253.             }
  254.         case 3:
  255.             asm {
  256.                 unlk a6
  257.                 move.l (a7)+, d0
  258.                 move.w (a7)+, d0
  259.                 jmp    myPrStlInit
  260.             }
  261.         case 4:
  262.             asm {
  263.                 unlk a6
  264.                 move.l (a7)+, d0
  265.                 move.w (a7)+, d0
  266.                 jmp    myPrJobInit
  267.             }
  268.         case 5:
  269.             asm {
  270.                 unlk a6
  271.                 move.l (a7)+, d0
  272.                 move.w (a7)+, d0
  273.                 jmp    myPrDlgMain
  274.             }
  275.         case 6:
  276.             asm {
  277.                 unlk a6
  278.                 move.l (a7)+, d0
  279.                 move.w (a7)+, d0
  280.                 jmp    myPrValidate
  281.             }
  282.         case 7:
  283.             asm {
  284.                 unlk a6
  285.                 move.l (a7)+, d0
  286.                 move.w (a7)+, d0
  287.                 jmp    myPrJobMerge
  288.             }
  289.     }  /* switch */
  290.     
  291.     /* We should not arrive here; Printing Manager has called a non-existent routine. */
  292.     SysError(5);  /* check bounds trap ??? */
  293. }  /* main */
  294.  
  295.  
  296. /*
  297. This function fills a print record with defaults. The default values are stored in the printer
  298. resource file, in PREC 0. This is easy. Then we check the fields of the print record for
  299. anything obviously illegal. If the default print record contains stuff that is bad, then we
  300. correct it and update the copy in the printer resource file. This should never happen, but
  301. some wise guy with a copy of ResEdit and more brains than sense may think he knows more than
  302. we do.
  303. */
  304.  
  305. pascal void
  306. myPrintDefault(hPrint)
  307. THPrint hPrint;
  308. {
  309.     THPrint    theDefault;
  310.     
  311.     HNoPurge(hPrint);  /* hopefully it is not nil */
  312.     
  313.     theDefault = (THPrint)GetResource('PREC', 0);
  314.     if (theDefault == nil) {
  315.         /* Add a new copy of the hard-coded print record as defaults. */
  316.         mkDefault(hPrint);
  317.         if ((theDefault = (THPrint)NewHandle((long)(sizeof(TPrint)))) != nil) {
  318.             /* Under MultiFinder this should probably have been allocated from the System Heap. */
  319.  
  320.             int saveRefNum;
  321.             
  322.             /* New default PREC is added to printer resource file */
  323.             saveRefNum = CurResFile();
  324.             UseResFile(
  325.                 HomeResFile(
  326.                     GetResource('PDEF', 4)
  327.                 )
  328.             );
  329.             
  330.             **theDefault = **hPrint;
  331.             AddResource(theDefault, 'PREC', 0, "\pDefault");
  332.             if (ResError() == noErr) {
  333.                 WriteResource(theDefault);
  334.                 HPurge(theDefault);
  335.             }
  336.             else {
  337.                 DisposHandle(theDefault);
  338.             }
  339.             UseResFile(saveRefNum);
  340.         }
  341.     }
  342.     else {
  343.         LoadResource(theDefault);
  344.         HNoPurge(theDefault);
  345.         if (!isValid(theDefault)) {
  346.             if (!isCorrectableAndWasUpdated(theDefault))  /* either correct it... */
  347.                 mkDefault(theDefault);  /* ...or use hard-coded defaults */
  348.             ChangedResource(theDefault);
  349.             /* if (ResError()...; there is not much we could do */
  350.             WriteResource(theDefault);
  351.         }  /* if not valid */
  352.         **hPrint = **theDefault;
  353.         HPurge(theDefault);
  354.     }
  355. }  /* myPrintDefault */
  356.  
  357.  
  358. /* Print style dialog. */
  359. pascal Boolean
  360. myPrStlDialog(hPrint)
  361. THPrint hPrint;
  362. {
  363.     return(myPrDlgMain(hPrint, (ProcPtr)myPrStlInit));
  364. }
  365.  
  366. /* Print job dialog. */
  367. pascal Boolean
  368. myPrJobDialog(hPrint)
  369. THPrint hPrint;
  370. {
  371.     return(myPrDlgMain(hPrint, (ProcPtr)myPrJobInit));
  372. }
  373.  
  374.  
  375. /* Style dialog initializer. */
  376. pascal TPPrDlg
  377. myPrStlInit(hPrint)
  378. THPrint hPrint;
  379. {
  380.     TPPrDlg    tp;
  381.     int iPaperSize;
  382.     TPrint descaledPrintRecord;
  383.     TPPrint pointerToThePreviousPrintRecordToProduceAFakeHandle;
  384.     
  385.     tp = allocatePrDialog();
  386.     (void)GetNewDialog(STYLEDIALOG, tp, (WindowPtr)(-1L));
  387.     /* We cannot determine if the resources were found or not (IM I-413). */
  388.     
  389.     /* Oops, IM doesn't say anything about 'hPrint': it may be full of zeros */
  390.     /* or from another driver and it is most likely unvalidated. ??? */
  391.     
  392.     /* Descale all rectangles accrding to printX[6] field. */
  393.     descaledPrintRecord = **hPrint;
  394.     {
  395.         Rect tr1, tr2;
  396.         
  397.         if ((descaledPrintRecord.printX[6] < 25)
  398.             || (descaledPrintRecord.printX[6] > 400))
  399.             descaledPrintRecord.printX[6] = 100;
  400.         
  401.         tr1.top = 0;
  402.         tr1.left = 0;
  403.         tr1.bottom = tr1.right = descaledPrintRecord.printX[6];
  404.         tr2.top = 0;
  405.         tr2.left = 0;
  406.         tr2.bottom = tr2.right = 100;
  407.  
  408.         MapRect(&(descaledPrintRecord.rPaper), &tr1, &tr2);
  409.         MapRect(&(descaledPrintRecord.prInfo.rPage), &tr1, &tr2);
  410.         ScalePt(&(descaledPrintRecord.prStl.iPageV), &tr1, &tr2);  /* V&H = Point ! */
  411.     }
  412.  
  413.     /* Determine the right paper size button by searching sizes in resource PREC 4: */
  414.     pointerToThePreviousPrintRecordToProduceAFakeHandle = &descaledPrintRecord;
  415.     iPaperSize = whichPaperSize(&pointerToThePreviousPrintRecordToProduceAFakeHandle);
  416.     
  417.     if (iPaperSize < 0) {
  418.         /* 'Other' paper size. */
  419.         setOtherPaperSizeInDialog(tp, &pointerToThePreviousPrintRecordToProduceAFakeHandle);
  420.     }
  421.     else {  /* standard size found */
  422.         int i;
  423.         
  424.         /* Determine sheet size.*/
  425.         i = iPaperSize & PAPER_MASK;
  426.         pushRadioButton(tp, A4BUTTON+i, A4BUTTON, OTHERBUTTON);
  427.         
  428.         /* Determine printer type.*/
  429.         i = iPaperSize & PRINTER_MASK;
  430.         if (i == PRINTER_HPDESKJET) {
  431.             forceValueToControls(tp, 0, APPLEWRITERBOX, APPLEWRITERBOX);
  432.             forceValueToControls(tp, 0, IMAGEBUTTON, LASERBUTTON);
  433.             deActivateControls(tp, IMAGEBUTTON, LASERBUTTON);
  434.         }
  435.         else {
  436.             forceValueToControls(tp, 1, APPLEWRITERBOX, APPLEWRITERBOX);
  437.             activateControls(tp, IMAGEBUTTON, LASERBUTTON);
  438.             i /= PRINTER_NUMBER_OF;
  439.             pushRadioButton(tp, IMAGEBUTTON+i, IMAGEBUTTON, LASERBUTTON);
  440.         }
  441.         
  442.         /* Determine 'Exact dimensions'. */
  443.         i = iPaperSize & PIXELS_MASK;
  444.         if (i == PIXELS_EXACT)
  445.             pushCheckBox(tp, EXACTBOX);
  446.     }
  447.     
  448.     /* Display scaling. */
  449.     setStringItemToInt(tp, STYLESCALENUM, descaledPrintRecord.printX[6]);
  450.     
  451.     /* Determine correct default orientation for this paper type (not yet). */
  452.     pushRadioButton(tp, TALLBUTTON, TALLBUTTON, WIDEBUTTON);
  453.     deActivateControls(tp, WIDEBUTTON, WIDEBUTTON);
  454.  
  455.     tp->pFltrProc = (ProcPtr)myStyleFilter;
  456.     tp->pItemProc = (ProcPtr)handleStyleItems;
  457.     tp->hPrintUsr = hPrint;
  458.     
  459.     return(tp);
  460. }  /* myPrStlInit */
  461.  
  462.  
  463. /* Job dialog initializer */
  464. pascal TPPrDlg
  465. myPrJobInit(hPrint)
  466. THPrint    hPrint;
  467. {
  468.     TPPrDlg    tp;
  469.     THPrint printRecordFromPreviousJob;
  470.     int resolution;
  471.     
  472.     tp = allocatePrDialog();
  473.     (void)GetNewDialog(JOBDIALOG, tp, (WindowPtr)(-1L));
  474.     /* We cannot determine if the resources were found or not (IM I-413). */
  475.     
  476.     /* Oops, IM doesn't say anything about 'hPrint': it may be full of zeros */
  477.     /* or from another driver and it is most likely unvalidated. ??? */
  478.     
  479.     if ((printRecordFromPreviousJob = (THPrint)GetResource('PREC', 1)) == nil)
  480.         resolution = (*hPrint)->prStl.wDev & RES_MASK;  /* use current one */
  481.     else {
  482.         LoadResource(printRecordFromPreviousJob);
  483.         resolution = (*printRecordFromPreviousJob)->prStl.wDev & RES_MASK;
  484.         HPurge(printRecordFromPreviousJob);
  485.     }
  486.     
  487.     /* Default resolution: */
  488.     pushRadioButton(tp, DPI300BUTTON+resolution, DPI300BUTTON, DRAFTBUTTON);
  489.  
  490.     /* Default is always "All pages" (according to IM II-158). */
  491.     pushRadioButton(tp, ALLBUTTON, ALLBUTTON, RANGEBUTTON);
  492.  
  493.     /* Sheet feeding taken from current print record instead of the one from */
  494.     /* previous job.  We want to suggest manual feeding for envelopes. */
  495.     if ((*hPrint)->prStl.feed == feedCut)
  496.         pushRadioButton(tp, MANUALBUTTON, AUTOMATICBUTTON, MANUALBUTTON);
  497.     else
  498.         pushRadioButton(tp, AUTOMATICBUTTON, AUTOMATICBUTTON, MANUALBUTTON);
  499.  
  500.     setStringItemToInt(tp, COPIESNUM, 1);  /* Always 1 according to IM II-158. */
  501.     
  502.     tp->pFltrProc = (ProcPtr)myJobFilter;
  503.     tp->pItemProc = (ProcPtr)handleJobItems;
  504.     tp->hPrintUsr = hPrint;
  505.     
  506.     return(tp);
  507. }  /* myPrJobInit */
  508.  
  509.  
  510. /* Printing dialog supervisor function. */
  511. pascal Boolean
  512. myPrDlgMain(hPrint, pDlgInit)
  513. THPrint hPrint;
  514. ProcPtr pDlgInit;
  515. {
  516.     TPPrDlg        tp;
  517.     WindowPtr    savePort;
  518.     
  519.     HNoPurge(hPrint);  /* hopefully it is not nil */
  520.     
  521.     /* Call dialog init routine. */
  522.     asm {
  523.         subq.l    #4,a7            ;; Room for function return
  524.         move.l    hPrint,-(a7)    ;; Pass handle to print record
  525.         move.l    pDlgInit,a0        ;; Get addr of dialog init routine
  526.         jsr        (a0)            ;; It's a Pascal routine
  527.         move.l    (a7)+,tp        ;; pop return value
  528.     }
  529.     
  530.     /* 'tp->pFltrProc' is set in init routine. */
  531.     /* 'tp->pItemProc' is set in init routine. */
  532.     tp->hPrintUsr = hPrint;
  533.     tp->fDone = FALSE;
  534.     tp->fDoIt = FALSE;
  535.     
  536.     GetPort(&savePort);
  537.     SetPort(tp);
  538.     ShowWindow(tp);
  539.  
  540.     while(!(tp->fDone)) {
  541.         int itemHit;
  542.         ProcPtr itemproc;
  543.         
  544.         ModalDialog(tp->pFltrProc, &itemHit);
  545.         
  546.         /* Reverse parameters on the call to pItemProc. */
  547.         /* The application is allowed to trap our 'pItemProc' and insert its own, */
  548.         /* so we must use the Pascal calling conventions here. */
  549.         itemproc = tp->pItemProc;
  550.         asm {
  551.             move.l    tp,-(a7)
  552.             move.w    itemHit,-(a7)
  553.             move.l    itemproc,a0
  554.             jsr        (a0)
  555.         }
  556.     }
  557.     SetPort(savePort);
  558.     {
  559.         Boolean tempDoIt;
  560.         
  561.         tempDoIt = tp->fDoIt;
  562.         
  563.         CloseDialog(tp);
  564.         DisposPtr(tp);
  565.         
  566.         if (tempDoIt)
  567.             (void)myPrValidate(hPrint);
  568.         return(tempDoIt);
  569.     }
  570. }  /* myPrDlgMain */
  571.  
  572.  
  573. /*
  574. Validate/update a print record. Check all the fields for compatibility with our driver. This is
  575. a three stage process. First, we check all fields to see whether they are within the bounds
  576. which our driver can handle. If they are, we return FALSE (no change). If not, we obtain a copy
  577. of the current default values from the printer resource file. Then we inspect these to see if
  578. they are valid. If the default values in the printer resource file are valid, we use them, 
  579. update the user's print record, and return TRUE (changed). Otherwise, we fall back on default
  580. values which we store in the code here. This three stage process provides some protection
  581. against the user who attempts to adjust the print record using a resource editor and 
  582. screws up.
  583. */
  584. pascal Boolean
  585. myPrValidate(hPrint)
  586. THPrint    hPrint;
  587. {
  588.     Boolean changedBecauseItWasNotValid;
  589.         
  590.     HNoPurge(hPrint);  /* hopefully it is not nil */
  591.     
  592.     if (isValid(hPrint))  /* we accept it 'as is' */
  593.         changedBecauseItWasNotValid = FALSE;
  594.     else if (isCorrectableAndWasUpdated(hPrint))  /* we accept it after modifications */
  595.         changedBecauseItWasNotValid = TRUE;
  596.     else {  /* it is garbage, get default one */
  597.         myPrintDefault(hPrint);
  598.         changedBecauseItWasNotValid = TRUE;
  599.     }
  600.  
  601.     return changedBecauseItWasNotValid;
  602. }  /* myPrValidate */
  603.  
  604.  
  605. pascal void
  606. myPrJobMerge(hPrintSrc, hPrintDst)
  607. THPrint    hPrintSrc, hPrintDst;
  608. {
  609.     HNoPurge(hPrintSrc);  /* hopefully it is not nil */
  610.     HNoPurge(hPrintDst);
  611.     
  612.     (void)myPrValidate(hPrintSrc);  /* IM II-159. */
  613.     (void)myPrValidate(hPrintDst);
  614.     
  615.     /* 'It then copies all the information set as a result of a job dialog...'  IM II-159. */
  616.     (*hPrintDst)->prJob.bJDocLoop = (*hPrintSrc)->prJob.bJDocLoop;
  617.     (*hPrintDst)->prStl.wDev = (*hPrintSrc)->prStl.wDev;
  618.     (*hPrintDst)->prJob.iFstPage = (*hPrintSrc)->prJob.iFstPage;
  619.     (*hPrintDst)->prJob.iLstPage = (*hPrintSrc)->prJob.iLstPage;
  620.     (*hPrintDst)->prJob.iCopies = (*hPrintSrc)->prJob.iCopies;
  621.     (*hPrintDst)->prStl.feed = (*hPrintSrc)->prStl.feed;
  622.     
  623.     /* '...it makes sure that all field of hPrintDst are */
  624.     /* internally self-consistent.'  IM II-159. */
  625.     (void)myPrValidate(hPrintDst);
  626. }  /* myPrJobMerge */
  627.  
  628.  
  629. pascal Boolean
  630. myStyleFilter(theDialog, theEvent, itemHit)
  631. TPPrDlg    theDialog;
  632. EventRecord    *theEvent;
  633. int            *itemHit;
  634. {
  635.     if (theEvent->what == updateEvt) {
  636.         if ((TPPrDlg)theEvent->message == theDialog)
  637.             frameButton(theDialog, OKBUTTON);
  638.         return FALSE;
  639.     }
  640.     else
  641.     if (theEvent->what == keyDown)
  642.         switch (theEvent->message & charCodeMask) {
  643.             case 0x03:
  644.             case 0x0D:
  645.                 *itemHit = OKBUTTON;  /* return and enter cause OK to be pressed */
  646.                 return TRUE;
  647.             
  648.             case 0x08:  /* BS */
  649.             case 0x09:  /* TAB */
  650.             case 0x1B:  /* Clear */
  651.             case 0x1C:  /* Left arrow */
  652.             case 0x1D:  /* Right arrow */
  653.             case 0x1E:  /* Up arrow */
  654.             case 0x1F:  /* Down arrow */
  655.             case '0':
  656.             case '1':
  657.             case '2':
  658.             case '3':
  659.             case '4':
  660.             case '5':
  661.             case '6':
  662.             case '7':
  663.             case '8':
  664.             case '9':
  665.                 return FALSE;  /* editing keys and numbers processed as usual */
  666.             
  667.             case '.':
  668.                 if (theEvent->modifiers & cmdKey) {
  669.                     /* Command-. = cancel */
  670.                     *itemHit = CANCELBUTTON;
  671.                     return TRUE;
  672.                 }
  673.                 /* else fall throug to default case: */
  674.             default:
  675.                 if (theDialog->dlg.editField < LASTSTYLEITEM) {
  676.                     SysBeep(8);
  677.                     theEvent->what = nullEvent;
  678.                 }
  679.                 return FALSE;
  680.         }  /* if & switch */
  681.     
  682.     return FALSE;
  683. }  /* myStyleFilter */
  684.  
  685.  
  686. pascal Boolean
  687. myJobFilter(theDialog, theEvent, itemHit)
  688. TPPrDlg    theDialog;
  689. EventRecord    *theEvent;
  690. int            *itemHit;
  691. {
  692.     if (theEvent->what == updateEvt) {
  693.         if ((TPPrDlg)theEvent->message == theDialog)
  694.             frameButton(theDialog, OKBUTTON);
  695.         return FALSE;
  696.     }
  697.     else
  698.     if (theEvent->what == keyDown)
  699.         switch (theEvent->message & charCodeMask) {
  700.             case 0x03:
  701.             case 0x0D:
  702.                 *itemHit = OKBUTTON;  /* return and enter cause OK to be pressed */
  703.                 return TRUE;
  704.             
  705.             case 0x08:  /* BS */
  706.             case 0x09:  /* TAB */
  707.             case 0x1B:  /* Clear */
  708.             case 0x1C:  /* Left arrow */
  709.             case 0x1D:  /* Right arrow */
  710.             case 0x1E:  /* Up arrow */
  711.             case 0x1F:  /* Down arrow */
  712.             case '0':
  713.             case '1':
  714.             case '2':
  715.             case '3':
  716.             case '4':
  717.             case '5':
  718.             case '6':
  719.             case '7':
  720.             case '8':
  721.             case '9':
  722.                 return FALSE;  /* editing keys and numbers processed as usual */
  723.             
  724.             case '.':
  725.                 if (theEvent->modifiers & cmdKey) {
  726.                     /* Command-. = cancel */
  727.                     *itemHit = CANCELBUTTON;
  728.                     return TRUE;
  729.                 }
  730.                 /* else fall throug to default case: */
  731.             default:
  732.                 if (theDialog->dlg.editField < LASTJOBITEM) {
  733.                     SysBeep(8);
  734.                     theEvent->what = nullEvent;
  735.                 }
  736.                 return FALSE;
  737.         }  /* if & switch */
  738.     
  739.     return FALSE;
  740. }  /* myJobFilter */
  741.  
  742.  
  743. /*
  744. The next routine handles the style dialog. Two possibilities exist.
  745. If the 'Cancel' button is hit then we signal quit. The print record is not changed.
  746. If the 'OK' button is hit, we validate the user's print record.
  747. */
  748.  
  749. pascal void
  750. handleStyleItems(tp, itemHit)
  751. TPPrDlg    tp;
  752. int        itemHit;
  753. {
  754.     if (itemHit >= A4BUTTON && itemHit <= ENVELOPEBUTTON) {
  755.         pushRadioButton(tp, itemHit, A4BUTTON, OTHERBUTTON);
  756.         blankStringItem(tp, PAPERWIDTHNUM);
  757.         blankStringItem(tp, PAPERHEIGHTNUM);
  758.         blankStringItem(tp, MARGINTOPNUM);
  759.         blankStringItem(tp, MARGINLEFTNUM);
  760.         blankStringItem(tp, MARGINBOTTOMNUM);
  761.         blankStringItem(tp, MARGINRIGHTNUM);
  762.         blankStringItem(tp, RESVNUM);
  763.         blankStringItem(tp, RESHNUM);
  764.         activateControls(tp, APPLEWRITERBOX, APPLEWRITERBOX);
  765.         forceValueToControls(tp, 0, APPLEWRITERBOX, APPLEWRITERBOX);  /* should be the previous user selection ??? */
  766.         forceValueToControls(tp, 0, IMAGEBUTTON, LASERBUTTON);
  767.         deActivateControls(tp, IMAGEBUTTON, LASERBUTTON);
  768.     }
  769.     else if (itemHit >= IMAGEBUTTON && itemHit <= LASERBUTTON)
  770.         pushRadioButton(tp, itemHit, IMAGEBUTTON, LASERBUTTON);
  771.     else if (itemHit >= TALLBUTTON && itemHit <= WIDEBUTTON)
  772.         pushRadioButton(tp, itemHit, TALLBUTTON, WIDEBUTTON);
  773.     else if (itemHit == EXACTBOX)
  774.         pushCheckBox(tp, itemHit);
  775.     else if (itemHit == APPLEWRITERBOX) {
  776.         if (pushCheckBox(tp, itemHit)) {
  777.             activateControls(tp, IMAGEBUTTON, LASERBUTTON);
  778.             pushRadioButton(tp, IMAGEBUTTON, IMAGEBUTTON, LASERBUTTON);  /* should be the previous user selection ??? */
  779.         }
  780.         else {
  781.             forceValueToControls(tp, 0, IMAGEBUTTON, LASERBUTTON);
  782.             deActivateControls(tp, IMAGEBUTTON, LASERBUTTON);
  783.         }
  784.     }
  785.     else if (itemHit == OTHERBUTTON) {
  786.         TPrint    Print;
  787.         TPPrint    pPrint;
  788.         
  789.         /* Default values for 'other' numeric fields from our standard sizes. */
  790.         pPrint = &Print;
  791.         setPaperSizeFieldsInPrintRecord(tp, &pPrint);
  792.         setOtherPaperSizeInDialog(tp, &pPrint);
  793.     }
  794.     else if ((itemHit == STYLEHELPBUTTON) || (itemHit == HPICON)) {
  795.         (void)Alert(STYLEHELPDIALOG, nil);
  796.     }
  797.     else if (itemHit == OKBUTTON) {
  798.         TPPrint pPrint;
  799.         
  800.         HLock(tp->hPrintUsr);
  801.         pPrint = *(tp->hPrintUsr);
  802.         
  803.         /* We should not overwrite everything in 'tp->hPrintUsr', instead, */
  804.         /* we trust our validation procedure to correct improper values. */
  805.         
  806.         if (controlIsOn(tp, OTHERBUTTON)) {
  807.             /* Paper rectangle. */
  808.             pPrint->rPaper.top = 0;
  809.             pPrint->rPaper.left = 0;
  810.             pPrint->rPaper.bottom = getStringItemAsInt(tp, PAPERHEIGHTNUM);
  811.             pPrint->rPaper.right = getStringItemAsInt(tp, PAPERWIDTHNUM);
  812.             OffsetRect(
  813.                 &(pPrint->rPaper),
  814.                 - getStringItemAsInt(tp, MARGINLEFTNUM),
  815.                 - getStringItemAsInt(tp, MARGINTOPNUM)
  816.             );
  817.             
  818.             /* Page rectangle. */
  819.             pPrint->prInfo.rPage.top = 0;
  820.             pPrint->prInfo.rPage.left = 0;
  821.             pPrint->prInfo.rPage.bottom = pPrint->rPaper.bottom - getStringItemAsInt(tp, MARGINBOTTOMNUM);
  822.             pPrint->prInfo.rPage.right = pPrint->rPaper.right - getStringItemAsInt(tp, MARGINRIGHTNUM);
  823.             pPrint->prInfo.iVRes = getStringItemAsInt(tp, RESVNUM);
  824.             pPrint->prInfo.iHRes = getStringItemAsInt(tp, RESHNUM);
  825.             pPrint->prInfoPT = pPrint->prInfo;
  826.             
  827.             /* Physical paper size. */
  828.             pPrint->prStl.iPageV =
  829.                 (int)(
  830.                     (long)getStringItemAsInt(tp, PAPERHEIGHTNUM)
  831.                     * (long)iPrPgFract
  832.                     / (long)pPrint->prInfo.iVRes
  833.                 );
  834.             pPrint->prStl.iPageH =
  835.                 (int)(
  836.                     (long)getStringItemAsInt(tp, PAPERWIDTHNUM)
  837.                     * (long)iPrPgFract
  838.                     / (long)pPrint->prInfo.iHRes
  839.                 );
  840.         }
  841.         else
  842.             setPaperSizeFieldsInPrintRecord(tp, tp->hPrintUsr);
  843.             /* This won't set anything if resource 'PREC' 4 is missing or malformed. ??? */
  844.         
  845.         /* Scale all rectangles accrding to 'Scale...' field. */
  846.         {
  847.             Rect tr1, tr2;
  848.             
  849.             tr1.top = 0;
  850.             tr1.left = 0;
  851.             tr1.bottom = tr1.right = 100;
  852.             tr2.top = 0;
  853.             tr2.left = 0;
  854.             tr2.bottom = tr2.right
  855.                 = pPrint->printX[6] = getStringItemAsInt(tp, STYLESCALENUM);
  856.  
  857.             MapRect(&(pPrint->rPaper), &tr1, &tr2);
  858.             MapRect(&(pPrint->prInfo.rPage), &tr1, &tr2);
  859.             ScalePt(&(pPrint->prStl.iPageV), &tr1, &tr2);  /* V&H = Point ! */
  860.         }
  861.         
  862. /***        if (controlIsOn(tp, WIDEBUTTON)) {
  863.             int temp;
  864.             
  865.             flipRect(&pPrint->prInfo.rPage);
  866.             flipRect(&pPrint->rPaper);
  867.             flipRect(&pPrint->prInfoPT.rPage);
  868.             temp = pPrint->prStl.iPageV;
  869.             pPrint->prStl.iPageV = (*tp->hPrintUsr)->prStl.iPageH;
  870.             pPrint->prStl.iPageH = temp;
  871.         }
  872. ***/
  873.         
  874.         HUnlock(tp->hPrintUsr);
  875.         
  876.         tp->fDone = TRUE;
  877.         tp->fDoIt = TRUE;
  878.     }  /* if OK */
  879.     else if (itemHit == CANCELBUTTON) {
  880.         tp->fDone = TRUE;
  881.         tp->fDoIt = FALSE;
  882.     }  /* if Cancel */
  883. }  /* handleStyleItems */
  884.  
  885.  
  886. void
  887. setPaperSizeFieldsInPrintRecord(tp, hPrint)
  888. TPPrDlg    tp;
  889. THPrint    hPrint;
  890. {
  891.     int temp1, temp2, temp3;
  892.     
  893.     temp1 = whichRadioButton(tp, A4BUTTON, ENVELOPEBUTTON);
  894.     if (temp1 < 0)
  895.         temp1 = PAPER_DEFAULT;
  896.         
  897.     if (controlIsOn(tp, APPLEWRITERBOX)) {
  898.         temp2 = whichRadioButton(tp, IMAGEBUTTON, LASERBUTTON);
  899.         temp2 *= PRINTER_NUMBER_OF;
  900.         if (temp2 < 0)
  901.             temp2 = PRINTER_DEFAULT;
  902.     }
  903.     else {
  904.         temp2 = PRINTER_HPDESKJET;
  905.     }
  906.     
  907.     if (controlIsOn(tp, EXACTBOX)) 
  908.         temp3 = PIXELS_EXACT;
  909.     else
  910.         temp3 = PIXELS_BEAUTIFUL;
  911.         
  912.     (void)updatePaperSize(hPrint, temp1+temp2+temp3);
  913. }  /* setPaperSizeFieldsInPrintRecord */
  914.  
  915.  
  916. void
  917. setOtherPaperSizeInDialog(tp, hPrint)
  918. TPPrDlg    tp;
  919. THPrint    hPrint;
  920. {
  921.     setStringItemToInt(tp, PAPERWIDTHNUM, ((*hPrint)->rPaper.right - (*hPrint)->rPaper.left));
  922.     setStringItemToInt(tp, PAPERHEIGHTNUM, ((*hPrint)->rPaper.bottom - (*hPrint)->rPaper.top));
  923.     setStringItemToInt(tp, MARGINTOPNUM, - (*hPrint)->rPaper.top);
  924.     setStringItemToInt(tp, MARGINLEFTNUM, - (*hPrint)->rPaper.left);
  925.     setStringItemToInt(tp, MARGINBOTTOMNUM, ((*hPrint)->rPaper.bottom - (*hPrint)->prInfo.rPage.bottom));
  926.     setStringItemToInt(tp, MARGINRIGHTNUM, ((*hPrint)->rPaper.right - (*hPrint)->prInfo.rPage.right));
  927.     setStringItemToInt(tp, RESVNUM, (*hPrint)->prInfo.iVRes);
  928.     setStringItemToInt(tp, RESHNUM, (*hPrint)->prInfo.iHRes);
  929.     
  930.     pushRadioButton(tp, OTHERBUTTON, A4BUTTON, OTHERBUTTON);
  931.     forceValueToControls(tp, 0, APPLEWRITERBOX, APPLEWRITERBOX);
  932.     deActivateControls(tp, APPLEWRITERBOX, APPLEWRITERBOX);
  933.     forceValueToControls(tp, 0, IMAGEBUTTON, LASERBUTTON);
  934.     deActivateControls(tp, IMAGEBUTTON, LASERBUTTON);
  935. }  /* setOtherPaperSizeInDialog */
  936.  
  937.  
  938. pascal void
  939. handleJobItems(tp, itemHit)
  940. TPPrDlg    tp;
  941. int        itemHit;
  942. {
  943.     if (itemHit >= DPI300BUTTON && itemHit <= DRAFTBUTTON)
  944.         pushRadioButton(tp, itemHit, DPI300BUTTON, DRAFTBUTTON);
  945.     else if ((itemHit >= ALLBUTTON) && (itemHit <= RANGEBUTTON))
  946.         pushRadioButton(tp, itemHit, ALLBUTTON, RANGEBUTTON);
  947.     else if ((itemHit >= FROMNUM) && (itemHit <= TONUM))  /* force 'From' button when page range is typed */
  948.         pushRadioButton(tp, RANGEBUTTON, ALLBUTTON, RANGEBUTTON);
  949.     else if ((itemHit >= AUTOMATICBUTTON) && (itemHit <= MANUALBUTTON))
  950.         pushRadioButton(tp, itemHit, AUTOMATICBUTTON, MANUALBUTTON);
  951.     else if (itemHit == JOBHELPBUTTON) {
  952.         (void)Alert(JOBHELPDIALOG, nil);
  953.     }
  954.     else if (itemHit == OKBUTTON) {
  955.         ptXprintGlobals xPrintGlobals;
  956.  
  957.         xPrintGlobals = GET_XPRINT_GLOBALS;
  958.         
  959.         /* If option key is held down, set permanent spool file flag. */
  960.         {
  961.             EventRecord tempEvent;
  962.             
  963.             (void)EventAvail(everyEvent, &tempEvent);
  964.             if (tempEvent.modifiers & optionKey) {
  965.                 xPrintGlobals->spoolFileIsNamedAndPermanent = TRUE;
  966.             }
  967.             else {
  968.                 xPrintGlobals->spoolFileIsNamedAndPermanent = FALSE;
  969.             }
  970.         }  /* if option */
  971.         
  972.         /* Spool file is not named -- permanent or temporary. */
  973.         xPrintGlobals->spoolFileAlreadyNamed = FALSE;
  974.         
  975.         /* Resolution: */
  976.         {
  977.             int temp;
  978.             
  979.             temp = whichRadioButton(tp, DPI300BUTTON, DRAFTBUTTON);
  980.             if (temp < 0)
  981.                 temp = RES_DEFAULT;
  982.             if (temp == RES_DRAFT)
  983.                 (*(tp->hPrintUsr))->prJob.bJDocLoop = bDraftLoop;
  984.             else
  985.                 (*(tp->hPrintUsr))->prJob.bJDocLoop = bSpoolLoop;
  986.             (*(tp->hPrintUsr))->prStl.wDev = iDevCItoh + temp;
  987.         }
  988.         
  989.         /* Page range: */
  990.         if (controlIsOn(tp, ALLBUTTON)) {
  991.             (*(tp->hPrintUsr))->prJob.iFstPage = iPrPgFst;
  992.             (*(tp->hPrintUsr))->prJob.iLstPage = iPrPgMax;
  993.         }
  994.         else {
  995.             int theInt;
  996.     
  997.             theInt = getStringItemAsInt(tp, FROMNUM);
  998.             (*(tp->hPrintUsr))->prJob.iFstPage =
  999.                 ( ((theInt<iPrPgFst)||(theInt>iPrPgMax)) ? iPrPgFst : theInt );
  1000.             
  1001.             theInt = getStringItemAsInt(tp, TONUM);
  1002.             (*(tp->hPrintUsr))->prJob.iLstPage =
  1003.                 ( ((theInt<iPrPgFst)||(theInt>iPrPgMax)) ? iPrPgMax : theInt );
  1004.         }
  1005.         {
  1006.             int theInt;
  1007.     
  1008.             theInt = getStringItemAsInt(tp, COPIESNUM);
  1009.             (*(tp->hPrintUsr))->prJob.iCopies = ( ((theInt<1)) ? 1 : theInt );
  1010.         }
  1011.         
  1012.         (*(tp->hPrintUsr))->printX[7] = getStringItemAsInt(tp, JOBSCALENUM);
  1013.         
  1014.         if (controlIsOn(tp, MANUALBUTTON))
  1015.             (*(tp->hPrintUsr))->prStl.feed = feedCut;
  1016.         else
  1017.             (*(tp->hPrintUsr))->prStl.feed = feedMechCut;
  1018.             
  1019.         tp->fDone = TRUE;
  1020.         tp->fDoIt = TRUE;
  1021.     }  /* if OK */
  1022.     else if (itemHit == CANCELBUTTON) {
  1023.         tp->fDone = TRUE;
  1024.         tp->fDoIt = FALSE;
  1025.     }
  1026. }  /* handleJobItems */
  1027.  
  1028.  
  1029. TPPrDlg
  1030. allocatePrDialog()
  1031. {
  1032.     TPPrDlg    thePointer;
  1033.     
  1034.     if ((thePointer = (TPPrDlg)NewPtr((long)(sizeof(TPrDlg) + 24))) == nil)  /* six extra longs ??? */
  1035.         SysError(25);
  1036.     return(thePointer);
  1037. }  /* allocatePrDialog */
  1038.  
  1039.  
  1040. #include "dialog_item_handling.c"
  1041.  
  1042. void
  1043. blankStringItem(theDialog, theItem)
  1044. TPPrDlg    theDialog;
  1045. int theItem;
  1046. {
  1047.     int        itemtype;
  1048.     Handle    itemhandle;
  1049.     Rect    itemrect;
  1050.     Str255    numAsString;
  1051.     
  1052.     if (theItem <= 0)
  1053.         return;
  1054.     numAsString[0] = 0;
  1055.     GetDItem(theDialog, theItem, &itemtype, &itemhandle, &itemrect);
  1056.     itemtype &= ~itemDisable;  /* regardless of whether item is disabled or not */
  1057.     if ((itemtype == statText) || (itemtype == editText))
  1058.         SetIText(itemhandle, numAsString);
  1059. }  /* blankStringItem */
  1060.  
  1061.  
  1062. Boolean
  1063. isValid(hPrint)
  1064. THPrint    hPrint;
  1065. {
  1066.     if ((*hPrint)->iPrVersion != PRINTING_MANAGER_VERSION) goto retFalse;
  1067.     if ((*hPrint)->prInfo.iDev != 0) goto retFalse;
  1068.     if (!(((*hPrint)->prInfo.iVRes == 72)
  1069.         || ((*hPrint)->prInfo.iVRes == 75))) goto retFalse;
  1070.     if (!(((*hPrint)->prInfo.iHRes == 72)
  1071.         || ((*hPrint)->prInfo.iHRes == 75)
  1072.         || ((*hPrint)->prInfo.iHRes == 80))) goto retFalse;
  1073.     if ((*hPrint)->prInfo.rPage.top != 0) goto retFalse;
  1074.     if ((*hPrint)->prInfo.rPage.left != 0) goto retFalse;
  1075.             
  1076. /* Paper size should be checked: rPaper, prInfo.rPage, prStl.iPageV/H. */
  1077.  
  1078.     if (!(((*hPrint)->prStl.feed == feedCut)
  1079.         || ((*hPrint)->prStl.feed == feedMechCut))) goto retFalse;
  1080.         
  1081.     if (((*hPrint)->prStl.wDev < (iDevCItoh+RES_300))
  1082.         || ((*hPrint)->prStl.wDev > (iDevCItoh+RES_DRAFT))) goto retFalse;
  1083.         
  1084.     /* if prInfoPT (print time) <> prInfo then goto retFalse ??? */
  1085.     /* prXInfo ??? */
  1086.     
  1087.     if ((*hPrint)->prJob.bJDocLoop == bDraftLoop)
  1088.         if ((*hPrint)->prStl.wDev != (iDevCItoh+RES_DRAFT)) goto retFalse;
  1089.  
  1090.     /* Scaling factors. */
  1091.     if (((*hPrint)->printX[6] < 25)
  1092.         || ((*hPrint)->printX[6] > 400)) goto retFalse;
  1093.     if (((*hPrint)->printX[7] < 25)
  1094.         || ((*hPrint)->printX[7] > 400)) goto retFalse;
  1095.         
  1096.     return TRUE;
  1097.     
  1098. retFalse:
  1099.     return FALSE;
  1100. }  /* isValid */
  1101.  
  1102.  
  1103. Boolean
  1104. isCorrectableAndWasUpdated(hPrint)
  1105. THPrint    hPrint;
  1106. {
  1107.     (*hPrint)->iPrVersion = PRINTING_MANAGER_VERSION;
  1108.     (*hPrint)->prInfo.iDev = 0;
  1109.     
  1110.     /* Update sizes and resolutions. ??? */
  1111.  
  1112.     if ((*hPrint)->prInfo.rPage.top != 0) goto retFalse;
  1113.     if ((*hPrint)->prInfo.rPage.left != 0) goto retFalse;
  1114.             
  1115.     if (!(((*hPrint)->prStl.feed == feedCut)
  1116.         || ((*hPrint)->prStl.feed == feedMechCut)))
  1117.         (*hPrint)->prStl.feed = feedMechCut;
  1118.         
  1119.     if (((*hPrint)->prStl.wDev < (iDevCItoh+RES_300))
  1120.         || ((*hPrint)->prStl.wDev > (iDevCItoh+RES_DRAFT)))
  1121.         (*hPrint)->prStl.wDev = iDevCItoh+RES_DEFAULT;
  1122.         
  1123.     /* Calculate banding & print time info ??? */
  1124.     /* prXInfo ??? */
  1125.     
  1126.     if ((*hPrint)->prJob.bJDocLoop == bDraftLoop)
  1127.         if ((*hPrint)->prStl.wDev != (iDevCItoh+RES_DRAFT))
  1128.             (*hPrint)->prStl.wDev = iDevCItoh+RES_DRAFT;
  1129.  
  1130.     /* Scaling factors. */
  1131.     if (((*hPrint)->printX[6] < 25)
  1132.         || ((*hPrint)->printX[6] > 400))
  1133.         (*hPrint)->printX[6] = 100;
  1134.     if (((*hPrint)->printX[7] < 25)
  1135.         || ((*hPrint)->printX[7] > 400))
  1136.         (*hPrint)->printX[7] = 100;
  1137.         
  1138.     return(TRUE);
  1139.     
  1140. retFalse:
  1141.     return(FALSE);
  1142. }  /* isCorrectableAndWasUpdated */
  1143.  
  1144.  
  1145. /*** This might be useful when 'Wide' orientation is implemented. 
  1146. flipRect(rect)
  1147. Rect    rect;
  1148. {
  1149.     asm {
  1150.         move.l    rect,a0
  1151.         move.l    (a0),d0
  1152.         swap    d0
  1153.         move.l    d0,(a0)+
  1154.         move.l    (a0),d0
  1155.         swap    d0
  1156.         move.l    d0,(a0)
  1157.     }
  1158. } ***/
  1159.  
  1160.  
  1161. /*
  1162. This function fills a print record with defaults, using coded values.
  1163. These values default to 75 dpi spool printing with max. print area.
  1164. */
  1165.  
  1166. void
  1167. mkDefault(hPrint)
  1168. THPrint    hPrint;
  1169. {
  1170.     (*hPrint)->iPrVersion = PRINTING_MANAGER_VERSION;
  1171.     (*hPrint)->prInfo.iDev = 0;  /* ? screen = 0 (as in Imagewriter) */
  1172.     
  1173.     
  1174.     /* This information normally comes from our paper size resource 'PREC' 4. */
  1175.     (*hPrint)->prInfo.iVRes = 75;
  1176.     (*hPrint)->prInfo.iHRes = 75;
  1177.     
  1178.     (*hPrint)->rPaper.top = -53;
  1179.     (*hPrint)->rPaper.left = -17;
  1180.     (*hPrint)->rPaper.bottom = 823;
  1181.     (*hPrint)->rPaper.right = 602;
  1182.     
  1183.     (*hPrint)->prInfo.rPage.top = 0;
  1184.     (*hPrint)->prInfo.rPage.left = 0;
  1185.     (*hPrint)->prInfo.rPage.bottom = 791;
  1186.     (*hPrint)->prInfo.rPage.right = 596;
  1187.     
  1188.     (*hPrint)->prStl.iPageV = 1403;
  1189.     (*hPrint)->prStl.iPageH = 992;
  1190.     (*hPrint)->prStl.feed = feedMechCut;
  1191.     
  1192.     
  1193.     /* These values are initialized by dialogs or only here. */
  1194.     (*hPrint)->prStl.wDev = iDevCItoh + RES_DEFAULT;    
  1195.     (*hPrint)->prStl.bPort = 0;  /* xPrintGlobals->currentSettings.port ??? */
  1196.     
  1197.     (*hPrint)->prInfoPT = (*hPrint)->prInfo;
  1198.     
  1199.     (*hPrint)->prXInfo.iRowBytes = 0;
  1200.     (*hPrint)->prXInfo.iBandV = 0;
  1201.     (*hPrint)->prXInfo.iBandH = 0;
  1202.     (*hPrint)->prXInfo.iDevBytes = 4;
  1203.         /* This is to satisfy applications which want to allocate */
  1204.         /* the banding buffer themselves. */
  1205.         /* We need more bytes than this _int_ can support. */
  1206.     (*hPrint)->prXInfo.iBands = 0;
  1207.     (*hPrint)->prXInfo.bPatScale = 0;
  1208.     (*hPrint)->prXInfo.bULThick = 0;
  1209.     (*hPrint)->prXInfo.bULOffset = 0;
  1210.     (*hPrint)->prXInfo.bULShadow = 0;
  1211.     (*hPrint)->prXInfo.scan = scanLR;
  1212.     (*hPrint)->prXInfo.bXInfoX = 0;
  1213.     
  1214.     (*hPrint)->prJob.iFstPage = 1;
  1215.     (*hPrint)->prJob.iLstPage = iPrPgMax;
  1216.     (*hPrint)->prJob.iCopies = 1;
  1217.     (*hPrint)->prJob.bJDocLoop = bSpoolLoop;
  1218.     (*hPrint)->prJob.fFromUsr = TRUE;
  1219.     (*hPrint)->prJob.pIdleProc = nil;
  1220.     (*hPrint)->prJob.pFileName = nil;
  1221.     (*hPrint)->prJob.iFileVol = 0;
  1222.     (*hPrint)->prJob.bFileVers = 0;
  1223.     (*hPrint)->prJob.bJobX = 0;
  1224.     
  1225.     (*hPrint)->printX[0] =
  1226.     (*hPrint)->printX[1] =
  1227.     (*hPrint)->printX[2] =
  1228.     (*hPrint)->printX[3] =
  1229.     (*hPrint)->printX[4] =
  1230.     (*hPrint)->printX[5] =
  1231.     (*hPrint)->printX[8] =
  1232.     (*hPrint)->printX[9] =
  1233.     (*hPrint)->printX[10] =
  1234.     (*hPrint)->printX[11] =
  1235.     (*hPrint)->printX[12] =
  1236.     (*hPrint)->printX[13] =
  1237.     (*hPrint)->printX[14] =
  1238.     (*hPrint)->printX[15] =
  1239.     (*hPrint)->printX[16] =
  1240.     (*hPrint)->printX[17] =
  1241.     (*hPrint)->printX[18] = 0;
  1242.     
  1243.     /* Scaling factors. */
  1244.     (*hPrint)->printX[6] = 100;
  1245.     (*hPrint)->printX[7] = 100;
  1246. }
  1247.  
  1248.  
  1249. Boolean
  1250. updatePaperSize(hPrint, iPaperSize)
  1251. THPrint    hPrint;
  1252. int iPaperSize;
  1253. {
  1254.     htAllSizesInfo hSizes;
  1255.     
  1256.     if ((hSizes = (htAllSizesInfo)GetResource('PREC', 4)) == nil)
  1257.         return(FALSE);
  1258.     
  1259.     LoadResource(hSizes);
  1260.  
  1261.     if ((iPaperSize < 0) || (iPaperSize > (*hSizes)->iNumberOfItems))
  1262.         return(FALSE);
  1263.         
  1264.     (*hPrint)->prInfo.iVRes = (*hSizes)->sSizeInfo[iPaperSize].iVRes;
  1265.     (*hPrint)->prInfo.iHRes = (*hSizes)->sSizeInfo[iPaperSize].iHRes;    
  1266.     (*hPrint)->rPaper = (*hSizes)->sSizeInfo[iPaperSize].rPaper;  
  1267.     (*hPrint)->prInfo.rPage = (*hSizes)->sSizeInfo[iPaperSize].rPage;    
  1268.     (*hPrint)->prStl.iPageV = (*hSizes)->sSizeInfo[iPaperSize].iPageV;
  1269.     (*hPrint)->prStl.iPageH = (*hSizes)->sSizeInfo[iPaperSize].iPageH;
  1270.     (*hPrint)->prStl.feed = (*hSizes)->sSizeInfo[iPaperSize].feed;
  1271.     (*hPrint)->prInfoPT = (*hPrint)->prInfo;    
  1272.  
  1273.     return(TRUE);
  1274. } /* updatePaperSize */
  1275.  
  1276.  
  1277. int
  1278. whichPaperSize(hPrint)
  1279. THPrint    hPrint;
  1280. {
  1281.     htAllSizesInfo hSizes;
  1282.     int iPaperSize;
  1283.     
  1284.     if ((hSizes = (htAllSizesInfo)GetResource('PREC', 4)) == nil)
  1285.         return(-1);
  1286.     
  1287.     LoadResource(hSizes);
  1288.  
  1289.     for (iPaperSize = 0; iPaperSize < (*hSizes)->iNumberOfItems; iPaperSize++)
  1290.         if ( ((*hPrint)->prInfo.iVRes == (*hSizes)->sSizeInfo[iPaperSize].iVRes)
  1291.             && ((*hPrint)->prInfo.iHRes == (*hSizes)->sSizeInfo[iPaperSize].iHRes)    
  1292.             && ((*hPrint)->rPaper.top == (*hSizes)->sSizeInfo[iPaperSize].rPaper.top)  
  1293.             && ((*hPrint)->rPaper.left == (*hSizes)->sSizeInfo[iPaperSize].rPaper.left)  
  1294.             && ((*hPrint)->rPaper.bottom == (*hSizes)->sSizeInfo[iPaperSize].rPaper.bottom)  
  1295.             && ((*hPrint)->rPaper.right == (*hSizes)->sSizeInfo[iPaperSize].rPaper.right)  
  1296.             && ((*hPrint)->prInfo.rPage.top == (*hSizes)->sSizeInfo[iPaperSize].rPage.top)    
  1297.             && ((*hPrint)->prInfo.rPage.left == (*hSizes)->sSizeInfo[iPaperSize].rPage.left)    
  1298.             && ((*hPrint)->prInfo.rPage.bottom == (*hSizes)->sSizeInfo[iPaperSize].rPage.bottom)    
  1299.             && ((*hPrint)->prInfo.rPage.right == (*hSizes)->sSizeInfo[iPaperSize].rPage.right)    
  1300.             && ((*hPrint)->prStl.iPageV == (*hSizes)->sSizeInfo[iPaperSize].iPageV)
  1301.             && ((*hPrint)->prStl.iPageH == (*hSizes)->sSizeInfo[iPaperSize].iPageH) )
  1302.             return(iPaperSize);
  1303.  
  1304.     return(-1);
  1305. } /* whichPaperSize */
  1306.